﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using Lib.Helper;
using MSIACCSL2.CoaServices;
using MSIACCSL2.Command;
using MSIACCSL2.InventoryServices;
using MSIACCSL2.ItemServices;
using MSIACCSL2.PalletServices;
using MSIACCSL2.SaldoAwalInventoryServices;
using MSIACCSL2.SatuanServices;
using MSIACCSL2.Struct;
using MSIACCSL2.UserServices;
using MSIACCSL2.Views.Inventory;
using MSIACCSL2.WarehouseServices;
using WcfService1.DTO;
using GetInventoriesCompletedEventArgs = MSIACCSL2.InventoryServices.GetInventoriesCompletedEventArgs;

namespace MSIACCSL2.ViewModels
{
    public class InventoryViewModel : ViewModelBase
    {
        #region Delegates

        public delegate void Completed(Object param);

        #endregion

        
        private static Search frmSearch;
        private static string OrderType;
        private static string PropertySort;
        public static Mode mode;
        private static InventoryDTO _inventory;
        private static Add frmAdd;
        public static Completed OnSearchCompleted;
        private readonly CoaServicesClient CoaClient;
        private readonly ItemServicesClient ItemClient;
        private readonly PalletServicesClient PalletClient;
        private readonly SaldoAwalInventoryServicesClient SaldoAwalClient;
        private readonly SatuanServicesClient SatuanClient;
        private readonly WarehouseServicesClient WarehouseClient;
        private readonly InventoryServiceClient client;
        private readonly ValidationHandler validationHandler;
        private int CurrentPage;
        private ObservableCollection<int> Pages;
        private UserServicesClient UserClient;
        private bool _IsBusy;
        private ObservableCollection<CoaDTO> _coas;
        private List<string> _errors;
        private List<String> _groupColumns;
        private PagedCollectionView _inventories;
        private ObservableCollection<ItemDTO> _items;
        private Visibility _messageVisibility;
        private PagedCollectionView _pageSources;
        private ObservableCollection<PalletDTO> _pallets;
        private ObservableCollection<SatuanDTO> _satuans;
        private ObservableCollection<WarehouseDTO> _warehouses;
        private Dictionary<string, object> criteria;
        private string expression;
        private Visibility _gridItemVisibility;
        private ObservableCollection<InventoryDTO> _inventoriDtos;


        public InventoryViewModel()
        {
            if (!DesignerProperties.IsInDesignTool)
            {
                client = new InventoryServiceClient();
                WarehouseClient = new WarehouseServicesClient();
                SatuanClient = new SatuanServicesClient();
                PalletClient = new PalletServicesClient();
                ItemClient = new ItemServicesClient();
                UserClient = new UserServicesClient();
                CoaClient = new CoaServicesClient();
                SaldoAwalClient = new SaldoAwalInventoryServicesClient();
                MessageVisibility = Visibility.Collapsed;
                GridItemVisibility = Visibility.Collapsed;

                OnPageChanged = new DelegateCommand(PageIndexChanged, CanPageIndexChanged);
                Save = new DelegateCommand(SaveInventory, CanSave);
                New = new DelegateCommand(NewInventory, CanNew);
                Edit = new DelegateCommand(EditInventory, CanEdit);
                Unload = new DelegateCommand(Release, CanUnload);
                SearchCommand = new DelegateCommand(SearchInventory, CanSearch);
                SearchResultCommand = new DelegateCommand(SearchResult, CanSearchResult);
                SearchPalletCommand = new DelegateCommand(GetPalletlist, CanSearchPallet);
                GetQtyUnitCommand = new DelegateCommand(GetQtyUnit, CanGetQtyUnit);
                GroupCommand = new DelegateCommand(GroupingInventory, CanGroupCommand);
                UploadCommand = new DelegateCommand(UploadHpp,CanUpload);
                validationHandler = new ValidationHandler();
                

                if (mode == Mode.Search || mode == Mode.Add)
                {      
                        GetWarehouseList();
                        GetSatuanList();
                        GetCOAList();
                        GetItemList(string.Empty);
                        LoadGroupColumn();
                        GetInventoryWarehouses(Inventory);
                }else if (mode == Mode.Edit )
                {
                    GetInventory(Inventory.SerialNumber);
                }
                else
                {
                    GetList(1, null);
                    LoadGroupColumn();
                }
            }
        }

        public void GetInventory(string serialNumber)
        {
            client.GetInventoryCompleted += client_GetInventoryCompleted;
            client.GetInventoryAsync(serialNumber);
        }

        void client_GetInventoryCompleted(object sender, GetInventoryCompletedEventArgs e)
        {
            client.GetInventoryCompleted -= client_GetInventoryCompleted;
            Inventory = e.Result;
            GetWarehouseList();
            GetSatuanList();
            GetCOAList();
            GetItemList(string.Empty);
            LoadGroupColumn();
            GetInventoryWarehouses(Inventory);
        }

        public PagedCollectionView Inventories
        {
            get { return _inventories; }

            private set
            {
                if (Inventories == value) return;
                _inventories = value;

                int i = (CurrentPage*30);
                foreach (object inventory  in Inventories)
                {
                    i += 1;

                    ((InventoryDTO) inventory).No = i;
                }

                FirePropertyChanged("Inventories");
                Inventories.CollectionChanged += Inventories_CollectionChanged;
            }
        }


        public PagedCollectionView PageSources
        {
            get { return _pageSources; }
            private set
            {
                if (PageSources == value) return;
                _pageSources = value;
                FirePropertyChanged("PageSources");
            }
        }


        public ObservableCollection<ItemDTO> Items
        {
            get { return _items; }
            private set
            {
                if (Items == value) return;
                _items = value;
                FirePropertyChanged("Items");
            }
        }

        public ObservableCollection<WarehouseDTO> Warehouses
        {
            get { return _warehouses; }
            private set
            {
                if (Warehouses == value) return;
                _warehouses = value;
                FirePropertyChanged("Warehouses");
            }
        }

        public ObservableCollection<SatuanDTO> Satuans
        {
            get { return _satuans; }
            private set
            {
                if (Satuans == value) return;
                _satuans = value;
                FirePropertyChanged("Satuans");
            }
        }

        public ObservableCollection<PalletDTO> Pallets
        {
            get { return _pallets; }
            private set
            {
                if (Pallets == value) return;
                _pallets = value;
                FirePropertyChanged("Pallets");
            }
        }

        public ObservableCollection<CoaDTO> Coas
        {
            get { return _coas; }
            private set
            {
                if (Coas == value) return;
                _coas = value;
                FirePropertyChanged("Coas");
            }
        }

        public bool IsBusy
        {
            get { return _IsBusy; }
            internal set
            {
                _IsBusy = value;
                FirePropertyChanged("IsBusy");
            }
        }

        public int RecordCount { get; set; }

        //Buat binding ke child form waktu mau edit
        public static InventoryDTO Inventory
        {
            get { return _inventory; }
            set
            {
                if (Inventory == value) return;
                _inventory = value;
                FirePropertyChanged2("Inventory");
            }
        }

        public List<string> Errors
        {
            get { return _errors; }
            private set
            {
                if (Errors == value) return;
                _errors = value;
                FirePropertyChanged("Errors");
            }
        }

        public Visibility MessageVisibility
        {
            get { return _messageVisibility; }
            private set
            {
                if (MessageVisibility == value) return;
                _messageVisibility = value;
                FirePropertyChanged("MessageVisibility");
            }
        }

        public Visibility GridItemVisibility
        {
            get { return _gridItemVisibility; }
            set
            {
                if (GridItemVisibility == value) return;
                _gridItemVisibility = value;
                FirePropertyChanged("GridItemVisibility");
            }
        }

        public List<string> GroupColumns
        {
            get { return _groupColumns; }
            private set
            {
                if (GroupColumns == value) return;
                _groupColumns = value;
                FirePropertyChanged("GroupColumns");
            }
        }


        public ICommand OnPageChanged { get; set; }
        public ICommand Save { get; set; }
        public ICommand New { get; set; }
        public ICommand Edit { get; set; }
        public ICommand Unload { get; set; }
        public ICommand SearchCommand { get; set; }
        public ICommand SearchResultCommand { get; set; }
        public ICommand SearchItemCommand { get; set; }
        public ICommand SearchPalletCommand { get; set; }
        public ICommand GetQtyUnitCommand { get; set; }

        public string Error
        {
            get { return null; }
        }

        public string this[string columnName]
        {
            get
            {
                if (validationHandler.BrokenRuleExists(columnName))
                {
                    return validationHandler[columnName];
                }
                return null;
            }
        }

        public ICommand GroupCommand { get; set; }

        public void Complete(Object param)
        {
            OnSearchCompleted(param);
        }

        private void LoadGroupColumn()
        {
            GroupColumns = new List<string>();
            GroupColumns.Add("--Reset--");
            GroupColumns.Add("Group");
            GroupColumns.Add("Subgroup");
            GroupColumns.Add("Item");
            GroupColumns.Add("Warehouse");
            GroupColumns.Add("Pallet");
        }

        private void Inventories_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (((PagedCollectionView) sender).SortDescriptions.Count > 0)
            {
                if (((PagedCollectionView) sender).SortDescriptions[0].PropertyName.ToLower() == "no") return;

                PropertySort = ((PagedCollectionView) sender).SortDescriptions[0].PropertyName;
                if (string.IsNullOrEmpty(OrderType))
                {
                    OrderType = "ASC";
                }
                else
                {
                    OrderType = OrderType == "ASC" ? OrderType = "DESC" : OrderType = "ASC";
                }
                GetList(1, PropertySort);
            }
        }

        public bool CanPageIndexChanged(Object param)
        {
            return true;
        }

        public bool CanSave(Object param)
        {
            return true;
        }

        public bool CanNew(Object param)
        {
            return true;
        }

        public bool CanEdit(Object param)
        {
            return true;
        }

        public bool CanUnload(Object param)
        {
            return true;
        }

        public bool CanSearch(Object param)
        {
            return true;
        }

        public bool CanSearchResult(Object param)
        {
            return true;
        }

        public bool CanSearchItem(Object param)
        {
            return true;
        }

        public bool CanSearchPallet(Object param)
        {
            return true;
        }

        public bool CanGetQtyUnit(Object param)
        {
            return true;
        }

        public void SaveInventory(Object param)
        {
            Inventory = (InventoryDTO) param;
            Validate();
            if (Errors.Count > 0) return;
            Inventory.created_by = GlobalVar.User.UserID;
            Inventory.modified_by = GlobalVar.User.UserID;
            client.SaveInventoryCompleted += SaveCompleted;
            client.SaveInventoryAsync(Inventory);
        }

        private void SaveCompleted(object sender, AsyncCompletedEventArgs e)
        {
            client.SaveInventoryCompleted -= SaveCompleted;
            MessageBox.Show("Success");
            frmAdd.DialogResult = true;
            Refresh();
        }

        public void SaveSaldoAwalInventory(Object param)
        {
            SaldoAwalClient.SaveInventoryCompleted += SaldoAwalClient_SaveInventoryCompleted;
            SaldoAwalClient.SaveInventoryAsync(param as InventoryDTO);
        }

        private void SaldoAwalClient_SaveInventoryCompleted(object sender, AsyncCompletedEventArgs e)
        {
            SaldoAwalClient.SaveInventoryCompleted -= SaldoAwalClient_SaveInventoryCompleted;
            Navigation.MyNavigation.GoBack();
        }

        public void GetList(int? page, string sortProp)
        {
            IsBusy = true;
            client.GetInventoriesCompleted += GetCompleted;
            client.GetInventoriesAsync(page ?? 1, sortProp, OrderType);
        }

        public void GetItemList(Object param)
        {
            ItemClient.GetItemByNameCompleted += ItemClient_GetItemByNameCompleted;
            ItemClient.GetItemByNameAsync(param.ToString());
        }

        private void ItemClient_GetItemByNameCompleted(object sender, GetItemByNameCompletedEventArgs e)
        {
            ItemClient.GetItemByNameCompleted -= ItemClient_GetItemByNameCompleted;
            Items = e.Result;
           if (Inventory.Item != null)
                    Inventory.Item =
                        Items.FirstOrDefault(x => x.ItemId == Inventory.Item.ItemId);
        }

        public void GetWarehouseList()
        {
            if (Inventory == null) return;
            WarehouseClient.GetAllWarehouseCompleted += new EventHandler<GetAllWarehouseCompletedEventArgs>(WarehouseClient_GetAllWarehouseCompleted);
            WarehouseClient.GetAllWarehouseAsync();
        }

        void WarehouseClient_GetAllWarehouseCompleted(object sender, GetAllWarehouseCompletedEventArgs e)
        {
            WarehouseClient.GetAllWarehouseCompleted -= new EventHandler<GetAllWarehouseCompletedEventArgs>(WarehouseClient_GetAllWarehouseCompleted);
            Warehouses = e.Result;
        }

        public void GetPalletlist(Object param)
        {
            PalletClient.GetPalletListCompleted += PalletClient_GetPalletListCompleted;
            PalletClient.GetPalletListAsync(param.ToString());
        }

        private void PalletClient_GetPalletListCompleted(object sender, GetPalletListCompletedEventArgs e)
        {
            PalletClient.GetPalletListCompleted -= PalletClient_GetPalletListCompleted;
            Pallets = e.Result;
        }

        public void GetSatuanList()
        {
            SatuanClient.GetAllSatuanCompleted += SatuanClient_GetAllSatuanCompleted;
            SatuanClient.GetAllSatuanAsync();
        }

        private void SatuanClient_GetAllSatuanCompleted(object sender, GetAllSatuanCompletedEventArgs e)
        {
            Satuans = e.Result;
            SatuanClient.GetAllSatuanCompleted -= SatuanClient_GetAllSatuanCompleted;
            if (mode == Mode.Edit)
            {
                if (Inventory.SatuanPack != null)
                    Inventory.SatuanPack = Satuans.FirstOrDefault(x => x.KodeSatuan == Inventory.SatuanPack.KodeSatuan);
                if (Inventory.SatuanUnit != null)
                    Inventory.SatuanUnit = Satuans.FirstOrDefault(x => x.KodeSatuan == Inventory.SatuanUnit.KodeSatuan);
            }
        }


        private void GetCompleted(object sender, GetInventoriesCompletedEventArgs e)
        {
            RecordCount = e.recordCount;
            if (PageSources == null) CreatePageNumber();
            client.GetInventoriesCompleted -= GetCompleted;
            Inventories = new PagedCollectionView(e.Result);
            IsBusy = false;
            Complete(this);
        }


        private void NewInventory(Object param)
        {
            mode = Mode.Add;
            Inventory = new InventoryDTO();
            frmAdd = new Add();
            frmAdd.Show();
        }


        public static void EditInventory(Object param)
        {
            mode = Mode.Edit;
            Inventory = (InventoryDTO) param;
            frmAdd = new Add();
            frmAdd.Show();
        }

        public  void GetInventoryWarehouses(InventoryDTO inventory)
        {
            client.GetInventoryWarehouseListCompleted += client_GetInventoryWarehouseListCompleted;
            client.GetInventoryWarehouseListAsync(inventory.SerialNumber);
        }

        private void client_GetInventoryWarehouseListCompleted(object sender,
                                                               GetInventoryWarehouseListCompletedEventArgs e)
        {
            client.GetInventoryWarehouseListCompleted -= client_GetInventoryWarehouseListCompleted;
            List<WarehouseDTO> warehouses =
                e.Result.Select((x) => new WarehouseDTO {KodeWarehouse = x.Warehouse.KodeWarehouse, Qty = x.Qty}).ToList
                    ();
            Inventory.Warehouses = new ObservableCollection<WarehouseDTO>(warehouses);
        }


        private void SearchInventory(Object param)
        {
            Inventory = new InventoryDTO();
            Inventory.IsStock = true;
            mode = Mode.Search;
            frmSearch = new Search();
            frmSearch.Show();
        }


        private void SearchResult(Object param)
        {
            criteria = new Dictionary<string, object>();

            foreach (PropertyInfo prop in Inventory.GetType().GetProperties())
            {
                if (prop.Name == "No" || prop.Name == "Subgroup" || prop.Name == "Group") continue;

                if (prop.PropertyType == typeof (Decimal))
                {
                    if ((Decimal) prop.GetValue(Inventory, null) == 0) continue;
                }

                if (prop.PropertyType == typeof (Int32))
                {
                    if ((Int32) prop.GetValue(Inventory, null) == 0) continue;
                }

                if (prop.PropertyType == typeof (Int64))
                {
                    if ((Int64) prop.GetValue(Inventory, null) == 0) continue;
                }

                if (prop.PropertyType == typeof (Double))
                {
                    if ((Double) prop.GetValue(Inventory, null) == 0) continue;
                }

                if (prop.PropertyType == typeof (String))
                {
                    if (String.IsNullOrEmpty((String) prop.GetValue(Inventory, null))) continue;
                }

                if (prop.PropertyType == typeof (DateTime))
                {
                    if (prop.GetValue(Inventory, null).ToString().Contains("0001")) continue;
                }

                if (prop.GetValue(Inventory, null) == null) continue;


                if (prop.PropertyType.Name.ToLower().Contains("dto"))
                {
                    foreach (PropertyInfo propertyInfo in prop.GetValue(Inventory, null).GetType().GetProperties())
                    {
                        if (propertyInfo.Name.ToLower().Contains("id") || propertyInfo.Name.ToLower().Contains("kode") ||
                            propertyInfo.Name.ToLower().Contains("serial"))
                        {
                            criteria.Add(prop.Name, propertyInfo.GetValue(prop.GetValue(Inventory, null), null));
                            break;
                        }
                    }
                }
                else
                {
                    criteria.Add(prop.Name, prop.GetValue(Inventory, null));
                }
            }

            expression = string.Empty;
            if (frmSearch.rblOr.IsChecked ?? false) expression = "OR";
            else expression = "AND";
            InventorySearch(criteria, expression,1);
        }

        private void InventorySearch(Dictionary<String, Object> criteria, string expression,int page)
        {
            frmSearch.DialogResult = true;
            IsBusy = true;
            Complete(this);
            if (criteria.ContainsKey("Warehouses")) criteria.Remove("Warehouses");
            client.GetInventoryByCriteriaCompleted += client_GetInventoryByCriteriaCompleted;
            client.GetInventoryByCriteriaAsync(criteria, expression, page);
        }

        private void client_GetInventoryByCriteriaCompleted(object sender, GetInventoryByCriteriaCompletedEventArgs e)
        {
            client.GetInventoryByCriteriaCompleted -= client_GetInventoryByCriteriaCompleted;
            Inventories = new PagedCollectionView(e.Result);
            if (RecordCount != e.recordCount)
            {
                RecordCount = e.recordCount;
                CreatePageNumber();
            }
            IsBusy = false;
        }


        private void CreatePageNumber()
        {
            Pages = new ObservableCollection<int>();
            for (int i = 0; i < RecordCount; i++)
            {
                Pages.Add(i);
            }
            PageSources = new PagedCollectionView(Pages);
        }


        private void PageIndexChanged(Object pageIndex)
        {
            //Jika Pertama kali jangan di Getlagi
            Inventory = null;
            if (Inventories != null && CurrentPage != (int) pageIndex)
            {
                CurrentPage = (int) pageIndex;
                if (mode == Mode.Search)
                    InventorySearch(criteria, expression, (int)pageIndex + 1);
                else if (String.IsNullOrEmpty(PropertySort))
                    GetList((int) pageIndex + 1, null);
                else GetList((int) pageIndex + 1, PropertySort);
            }
        }


        public void Release(Object param)
        {
            param = null;
            OrderType = null;
            PropertySort = null;
            mode = Mode.Idle;
        }


        public void Refresh()
        {
            if (Inventories == null)
                GetList(1, null);
            else
                Complete(this);
        }


        public void Validate(string error = null)
        {
            Errors = new List<string>();
            if (string.IsNullOrEmpty(Inventory.SerialNumber))
                Errors.Add("Serial Number harus diisi!");
            if (!string.IsNullOrEmpty(error))
                Errors.Add(error);

            if (Errors.Count > 0)
            {
                MessageVisibility = Visibility.Visible;
            }
            else
            {
                MessageVisibility = Visibility.Collapsed;
            }
        }

        private void GetQtyUnit(Object param)
        {
            Inventory.QtyUnit = (Inventory.Panjang)*(Inventory.Lebar)*(Inventory.Tinggi)/Inventory.SatuanUnit.Pengali;
        }


        private void GetCOAList()
        {
            CoaClient.GetAllCoaCompleted += CoaClient_GetAllCoaCompleted;
            CoaClient.GetAllCoaAsync();
        }



        private void CoaClient_GetAllCoaCompleted(object sender, GetAllCoaCompletedEventArgs e)
        {
            CoaClient.GetAllCoaCompleted += CoaClient_GetAllCoaCompleted;

            Coas = e.Result;
            //Coas =
            //    new ObservableCollection<CoaDTO>(
            //        Coas.Where(
            //            c => c.Category == Convert.ToInt16(AccountType.COGS).ToString() || c.Category == Convert.ToInt16(AccountType.Assets).ToString()));
            
            if (mode == Mode.Edit)
            {
                if (Inventory.CoaHpp != null)
                    Inventory.CoaHpp = Coas.FirstOrDefault(x => x.AccountNumber == Inventory.CoaHpp).AccountNumber;
                if (Inventory.CoaInventory != null)
                    Inventory.CoaInventory =
                        Coas.FirstOrDefault(x => x.AccountNumber == Inventory.CoaInventory).AccountNumber;
            }
        }


        public bool CanGroupCommand(Object param)
        {
            return true;
        }

        private void GroupingInventory(Object param)
        {
            string strgroup = param.ToString();

            if (strgroup.Contains("Reset")) Inventories.GroupDescriptions.Clear();

            if (strgroup == "Item")
            {
                var itemConverter = new ItemConverter();
                Inventories.GroupDescriptions.Add(new PropertyGroupDescription(strgroup, itemConverter));
            }
            else if (strgroup == "Warehouse")
            {
                var warehouseConverter = new WarehouseConverter();
                Inventories.GroupDescriptions.Add(new PropertyGroupDescription(strgroup, warehouseConverter));
            }
            else if (strgroup == "Pallet")
            {
                var palletConverter = new PalletConverter();
                Inventories.GroupDescriptions.Add(new PropertyGroupDescription(strgroup, palletConverter));
            }
            else if (strgroup == "Group")
            {
                var groupConverter = new GroupConverter();
                Inventories.GroupDescriptions.Add(new PropertyGroupDescription(strgroup));
            }
            else if (strgroup == "Subgroup")
            {
                var subGroupConverter = new SubGroupConverter();
                Inventories.GroupDescriptions.Add(new PropertyGroupDescription(strgroup));
            }
        }


        public ObservableCollection<InventoryDTO> InventoryDtos
        {
            get { return _inventoriDtos; }
            set
            {
                if (ReferenceEquals(InventoryDtos,value) || value==null)return;
                _inventoriDtos = value;
                FirePropertyChanged("InventoryDtos");
            }
        }


        public void LoadDetailFromFile(Object param)
        {
            ImportHelper importHelper = new ImportHelper();
            IEnumerable<List<dynamic>> sourcesOld;
            importHelper.BrowseExcelFile(out sourcesOld);
            var sources = importHelper.LoadExcellFile(importHelper.listSheetNames.FirstOrDefault());
            InventoryDtos = new ObservableCollection<InventoryDTO>();
           
            if (sourcesOld == null || sourcesOld.Count() == 0)
            {
                if (sources != null)
                    foreach (dynamic data in sources)
                    {
                        string noLog = data.A;
                        decimal hpp = Decimal.Parse(data.B);
                        if (string.IsNullOrEmpty(noLog)) continue;
                        InventoryDtos.Add(new InventoryDTO() { SerialNumber = noLog,UnitPrice = hpp});
                    }

            }
            else
            {
                int i = 0;
                foreach (var data in sourcesOld)
                {
                    if (i > 0)
                    {
                        string noLog = data[0];
                        decimal hpp = Decimal.Parse(data[1]);
                        if (string.IsNullOrEmpty(noLog)) continue;
                        InventoryDtos.Add(new InventoryDTO() { SerialNumber = noLog, UnitPrice = hpp });
                    }
                    i++;
                }
            }
        }


        public ICommand UploadCommand { get; set; }
        public bool CanUpload(Object param)
        {
            return true;
        }
        public void UploadHpp(Object param)
        {
            if (InventoryDtos == null)
            {
                MessageBox.Show("Pilih Select File dulu!");
                return;
            }
            IsBusy = true;
            client.UpdateHppCompleted += new EventHandler<AsyncCompletedEventArgs>(client_UpdateHppCompleted);
            client.UpdateHppAsync((ObservableCollection<InventoryDTO>) param);
        }

        void client_UpdateHppCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }

        client.UpdateHppCompleted -= new EventHandler<AsyncCompletedEventArgs>(client_UpdateHppCompleted);
            IsBusy = false;
            MessageBox.Show("Upload Selesai!");
        }
    }


    public class WarehouseConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null)
            {
                return ((dynamic) value).KodeWarehouse;
            }
            else
            {
                return string.Empty;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }


    public class PalletConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null)
            {
                return ((dynamic) value).KodePallet;
            }
            else
            {
                return string.Empty;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

    public class ItemConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null)
            {
                return ((dynamic) value).ItemName;
            }
            else
            {
                return string.Empty;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

    public class SatuanConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null)
            {
                return ((dynamic) value).KodeSatuan;
            }
            else
            {
                return string.Empty;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

    public class InventoryWrapViewModel : ViewModelBase
    {
        private readonly InventoryServiceClient client;

        public InventoryWrapViewModel()
        {
            if (!DesignerProperties.IsInDesignTool)
            {
                EditCommand = new DelegateCommand(Edit, CanEditCommand);
                DeleteCommand = new DelegateCommand(Delete, CanDeleteCommand);
                SaldoAwalCommand = new DelegateCommand(EntrySaldoAwal, CanSaldoAwal);
                client = new InventoryServiceClient();
            }
        }

        public InventoryDTO Inventory { get; set; }
        public ICommand EditCommand { get; set; }
        public ICommand DeleteCommand { get; set; }
        public ICommand SaldoAwalCommand { get; set; }


        public bool CanEditCommand(Object param)
        {
            return true;
        }

        public bool CanDeleteCommand(Object param)
        {
            return true;
        }

        public bool CanSaldoAwal(Object param)
        {
            return true;
        }

        public void EntrySaldoAwal(Object param)
        {
            InventoryViewModel.mode = Mode.Edit;
            Navigation.MyNavigation.Navigate(new Uri("/Inventory/frmAdd", UriKind.Relative));
            Navigation.Args = param;
        }


        public void Edit(Object param)
        {
            InventoryViewModel.mode = Mode.Edit;
            InventoryViewModel.EditInventory(param);
        }

        public void Delete(Object param)
        {
            client.DeleteInventoryCompleted += client_DeleteInventoryCompleted;
            client.DeleteInventoryAsync((InventoryDTO) param);
        }

        private void client_DeleteInventoryCompleted(object sender, AsyncCompletedEventArgs e)
        {
            client.DeleteInventoryCompleted -= client_DeleteInventoryCompleted;
            MessageBox.Show("Delete Success!");
            InventoryViewModel.mode = Mode.Idle;
            var VM = new InventoryViewModel();
        }
    }
}